package top.huntwolf.admin.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import top.huntwolf.admin.common.enums.CodeMsg;
import top.huntwolf.admin.exception.ServiceException;
import top.huntwolf.admin.pojo.cmsUser.CMSUser;
import top.huntwolf.admin.pojo.JwtToken;
import top.huntwolf.admin.pojo.cmsUser.Permission;
import top.huntwolf.admin.pojo.shop.ShopContext;
import top.huntwolf.admin.service.CMSUserService;
import top.huntwolf.admin.utils.TokenUtil;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;




public class JwtRealm extends AuthorizingRealm {
    @Autowired
    private CMSUserService cmsUserService;

    /**
     * 限定只能处理自定义JWTtoken
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        Subject subject = SecurityUtils.getSubject();
        CMSUser user = (CMSUser) subject.getPrincipal();

        List<Permission> permissionList = cmsUserService.searchPermission(user);
        List<String> permissions = permissionList.stream().map(Permission::getPermission).collect(Collectors.toList());

        SimpleAuthorizationInfo info  = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissions);
        return info;
    }

    /**
     * 认证
     * @param auth 传入的jwtToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) {

        JwtToken jwtToken = (JwtToken) auth;
        if (jwtToken.getPrincipal() == null) {
            //jwt参数异常
            throw new ServiceException(CodeMsg.SESSION_ERROR);
        }
        String userName = jwtToken.getPrincipal().toString();
        CMSUser user = cmsUserService.findUserByName(userName);

        //用户不存在
        if (user == null) {
            throw new ServiceException(CodeMsg.USER_NOT_FOUND);
        }

        String token = jwtToken.getCredentials().toString();

        if (!TokenUtil.verify(token,userName)) {
            throw new ServiceException(CodeMsg.SESSION_ERROR);
        }
        ShopContext.set(user.getStoreId());


        return new SimpleAuthenticationInfo(user,userName,getName());
    }
}
